﻿using System.Linq;
using System.Security.Claims;
using Hangfire.Dashboard;
using Microsoft.AspNetCore.Http;
using EFCore.Core.Secutiry.Claims;


namespace EFCore.Hangfire
{
    /// <summary>
    /// Dashboard角色权限过滤器
    /// </summary>
    public class RoleDashboardAuthorizationFilter : IDashboardAuthorizationFilter
    {
        private readonly string[] _roles;
        private readonly string[] _userIds;
        private readonly string _accessToken;

        /// <summary>
        /// 初始化一个<see cref="RoleDashboardAuthorizationFilter"/>类型的新实例
        /// </summary>
        public RoleDashboardAuthorizationFilter(string[] roles, string[] userIds, string accessToken = "")
        {
            _roles = roles;
            _userIds = userIds;
            _accessToken = accessToken;
        }

        public bool Authorize(DashboardContext context)
        {
            HttpContext httpContext = context.GetHttpContext();
            ClaimsPrincipal principal = httpContext.User;
            ClaimsIdentity identity = principal.Identity as ClaimsIdentity;
            if (identity == null)
            {
                return false;
            }
            
            bool blnChkRoleRst = false, blnChkUserRst = false, blnChkAccessToken = false;

            if (!string.IsNullOrWhiteSpace(_accessToken))
            {
                string accToken = context.Request.GetQuery("accessToken");
                if (!string.IsNullOrWhiteSpace(accToken))
                {
                    httpContext.Response.Cookies.Append("accessToken", accToken, new CookieOptions {
                        HttpOnly = true,
                        SameSite = SameSiteMode.Strict,
                        Secure = false,
                        Expires = null,
                        Path = "/hangfire"
                    });
                }
                else
                {
                    httpContext.Request.Cookies.TryGetValue("accessToken", out accToken);
                }
                blnChkAccessToken = !string.IsNullOrWhiteSpace(accToken) && _accessToken == accToken;
                if (blnChkAccessToken)
                {
                    return true;
                }
            }

            if (identity.IsAuthenticated) //已认证
            {
                if (_roles.Length > 0) //根据用户角色授权
                {
                    string[] roles = identity.GetRoles();
                    blnChkRoleRst = _roles.Intersect(roles).Any();
                }
                if (_userIds.Length > 0) //根据用户编号授权
                {
                    string userId = identity.GetUserId<string>();
                    blnChkUserRst = !string.IsNullOrWhiteSpace(userId) && _userIds.Contains(userId);
                }
            }

            return blnChkRoleRst || blnChkUserRst; // || blnChkAccessToken
        }
    }
}